package com.eight.cloud.gateway.handler;


import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.eight.cloud.core.global.result.Result;
import com.eight.cloud.core.global.result.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.support.NotFoundException;
import org.springframework.context.annotation.Primary;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.lang.NonNullApi;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebExceptionHandler;
import reactor.core.publisher.Mono;

import java.net.ConnectException;

import static com.eight.cloud.core.global.result.ResultCode.BAD_REQUEST;

/**
 * @ClassName: JsonExceptionHandler
 * @Author: TXC
 * @Date: 2024-10-20 11:04
 **/
@Component
@Primary
@Order(Ordered.HIGHEST_PRECEDENCE)
@Slf4j
public class JsonExceptionHandler implements WebExceptionHandler {

    @Override
    public Mono<Void> handle(ServerWebExchange exchange, Throwable throwable) {
        ObjectMapper objectMapper = new ObjectMapper();
        // 获取表单提供的数据
        ServerHttpResponse response = exchange.getResponse();
        response.getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
        Result<Object> vo;
        log.error("异常信息:{}", throwable.getMessage(), throwable);
        if (throwable instanceof ResponseStatusException && ((ResponseStatusException) throwable).getStatus() == HttpStatus.NOT_FOUND) {
            vo = Result.fail(ResultCode.NO_FOUND);
        } else if (throwable instanceof NotFoundException){
            vo = Result.fail(BAD_REQUEST);
        } else {
            vo = Result.fail(ResultCode.ERROR, throwable.getMessage());
        }
        return response.writeWith(Mono.fromSupplier(() -> {
            byte[] bytes;
            try {
                bytes = objectMapper.writeValueAsBytes(vo);
            } catch (JsonProcessingException e) {
                response.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
                bytes = "JSON 转换异常！".getBytes();
            }
            return response.bufferFactory().wrap(bytes);
        }));
    }

}
